package org.jeecg.modules.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.api.dto.message.*;
import org.jeecg.common.aspect.UrlMatchEnum;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.constant.WebsocketConst;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.*;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.SysAnnmentTypeEnum;
import org.jeecg.common.util.YouBianCodeUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.common.utils.BeanObjUtil;
import org.jeecg.modules.common.utils.DateUtil;
import org.jeecg.modules.common.utils.MapBeanUtils;
import org.jeecg.modules.message.entity.SysMessageTemplate;
import org.jeecg.modules.message.handle.impl.EmailSendMsgHandle;
import org.jeecg.modules.message.service.ISysMessageTemplateService;
import org.jeecg.modules.message.websocket.WebSocket;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.mapper.*;
import org.jeecg.modules.system.service.*;
import org.jeecg.modules.system.util.BaseTransfer;
import org.jeecg.modules.system.util.ConversiontUtil;
import org.jeecg.modules.system.util.SecurityUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import javax.annotation.Resource;
import javax.management.relation.Role;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.*;

/**
 * @Description: 底层共通业务API，提供其他独立模块调用
 * @Author: scott
 * @Date:2019-4-20 
 * @Version:V1.0
 */
@Slf4j
@Service
public class SysBaseApiImpl implements ISysBaseAPI {
	/** 当前系统数据库类型 */
	private static String DB_TYPE = "";
	@Autowired
	private ISysMessageTemplateService sysMessageTemplateService;
	@Resource
	private SysLogMapper sysLogMapper;
	@Resource
	private SysUserMapper userMapper;
	@Resource
	private SysUserRoleMapper sysUserRoleMapper;
	@Autowired
	private ISysDepartService sysDepartService;
	@Autowired
	private ISysDictService sysDictService;
	@Resource
	private SysAnnouncementMapper sysAnnouncementMapper;
	@Resource
	private SysAnnouncementSendMapper sysAnnouncementSendMapper;
	@Resource
    private WebSocket webSocket;
	@Resource
	private SysRoleMapper roleMapper;
	@Resource
	private SysDepartMapper departMapper;
	@Resource
	private SysCategoryMapper categoryMapper;

	@Autowired
	private ISysDataSourceService dataSourceService;
	@Autowired
	private ISysUserDepartService sysUserDepartService;
	@Resource
	private SysPermissionMapper sysPermissionMapper;
	@Autowired
	private ISysPermissionDataRuleService sysPermissionDataRuleService;

	@Autowired
	private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
	@Autowired
	private ThirdAppDingtalkServiceImpl dingtalkService;

	@Autowired
	ISysCategoryService sysCategoryService;
	@Autowired
	ISysUserService sysUserService;
	@Autowired
	ISysTenantService sysTenantService;
	@Autowired
	ISysRoleService sysRoleService;
	@Autowired
	ISysUserRoleService sysUserRoleService;
	@Autowired
	ISysPermissionService sysPermissionService;
	@Autowired
	ISysRolePermissionService sysRolePermissionService;

	@Override
	@Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
	public LoginUser getUserByName(String username) {
		if(oConvertUtils.isEmpty(username)) {
			return null;
		}
		LoginUser loginUser = new LoginUser();
		SysUser sysUser = userMapper.getUserByName(username);
		if(sysUser==null) {
			return null;
		}
		BeanUtils.copyProperties(sysUser, loginUser);
		return loginUser;
	}
	/**
	 * 根据用户信息查询所有的用户列表
	 * @param loginUser
	 */
	@Override
	public List<LoginUser> getUserListByLoginUser(LoginUser loginUser) {
		if(oConvertUtils.isEmpty(loginUser)) {
			return null;
		}
		SysUser sysUser = new SysUser();
		BeanObjUtil.copyDeepCloneProperties(loginUser,sysUser); //复制值：深度复制
		List<SysUser> sysUserList = userMapper.getUserListByLoginUser( sysUser);
		List<LoginUser> loginUserList = new ArrayList<LoginUser>();
//		BeanObjUtil.copyDeepClonePropertiesByObjList(sysUserList,loginUserList);
//		loginUserList = BeanObjUtil.copyDeepClonePropertiesByObjList(sysUserList,LoginUser.class);
		for(int i=0;i< sysUserList.size() ;i++) {
			LoginUser newLoginUser = new LoginUser();
			BeanObjUtil.copyDeepCloneProperties(sysUserList.get(i),newLoginUser);
			loginUserList.add(newLoginUser);
		}
		return loginUserList;
	}


	@Override
	public String translateDictFromTable(String table, String text, String code, String key) {
		return sysDictService.queryTableDictTextByKey(table, text, code, key);
	}

	@Override
	public String translateDict(String code, String key) {
		return sysDictService.queryDictTextByKey(code, key);
	}

	@Override
	public List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username) {
		List<SysPermission> currentSyspermission = null;
		if(oConvertUtils.isNotEmpty(component)) {
			//1.通过注解属性pageComponent 获取菜单
			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
			query.eq(SysPermission::getDelFlag,0);
			query.eq(SysPermission::getComponent, component);
			currentSyspermission = sysPermissionMapper.selectList(query);
		}else {
			//1.直接通过前端请求地址查询菜单
			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
			query.eq(SysPermission::getMenuType,2);
			query.eq(SysPermission::getDelFlag,0);
			query.eq(SysPermission::getUrl, requestPath);
			currentSyspermission = sysPermissionMapper.selectList(query);
			//2.未找到 再通过自定义匹配URL 获取菜单
			if(currentSyspermission==null || currentSyspermission.size()==0) {
				//通过自定义URL匹配规则 获取菜单（实现通过菜单配置数据权限规则，实际上针对获取数据接口进行数据规则控制）
				String userMatchUrl = UrlMatchEnum.getMatchResultByUrl(requestPath);
				LambdaQueryWrapper<SysPermission> queryQserMatch = new LambdaQueryWrapper<SysPermission>();
				// update-begin-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
				//queryQserMatch.eq(SysPermission::getMenuType, 1);
				// update-end-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1
				queryQserMatch.eq(SysPermission::getDelFlag, 0);
				queryQserMatch.eq(SysPermission::getUrl, userMatchUrl);
				if(oConvertUtils.isNotEmpty(userMatchUrl)){
					currentSyspermission = sysPermissionMapper.selectList(queryQserMatch);
				}
			}
			//3.未找到 再通过正则匹配获取菜单
			if(currentSyspermission==null || currentSyspermission.size()==0) {
				//通过正则匹配权限配置
				String regUrl = getRegexpUrl(requestPath);
				if(regUrl!=null) {
					currentSyspermission = sysPermissionMapper.selectList(new LambdaQueryWrapper<SysPermission>().eq(SysPermission::getMenuType,2).eq(SysPermission::getUrl, regUrl).eq(SysPermission::getDelFlag,0));
				}
			}
		}
		if(currentSyspermission!=null && currentSyspermission.size()>0){
			List<SysPermissionDataRuleModel> dataRules = new ArrayList<SysPermissionDataRuleModel>();
			for (SysPermission sysPermission : currentSyspermission) {
				// update-begin--Author:scott Date:20191119 for：数据权限规则编码不规范，项目存在相同包名和类名 #722
				List<SysPermissionDataRule> temp = sysPermissionDataRuleService.queryPermissionDataRules(username, sysPermission.getId());
				if(temp!=null && temp.size()>0) {
					//dataRules.addAll(temp);
					dataRules = oConvertUtils.entityListToModelList(temp,SysPermissionDataRuleModel.class);
				}
				// update-end--Author:scott Date:20191119 for：数据权限规则编码不规范，项目存在相同包名和类名 #722
			}
			return dataRules;
		}
		return null;
	}

	/**
	 * 匹配前端传过来的地址 匹配成功返回正则地址
	 * AntPathMatcher匹配地址
	 *()* 匹配0个或多个字符
	 *()**匹配0个或多个目录
	 */
	private String getRegexpUrl(String url) {
		List<String> list = sysPermissionMapper.queryPermissionUrlWithStar();
		if(list!=null && list.size()>0) {
			for (String p : list) {
				PathMatcher matcher = new AntPathMatcher();
				if(matcher.match(p, url)) {
					return p;
				}
			}
		}
		return null;
	}

	@Override
	public SysUserCacheInfo getCacheUser(String username) {
		SysUserCacheInfo info = new SysUserCacheInfo();
		info.setOneDepart(true);
		LoginUser user = this.getUserByName(username);
		if(user!=null) {
			info.setSysUserCode(user.getUsername());
			info.setSysUserName(user.getRealname());
			info.setSysOrgCode(user.getOrgCode());
			info.setTenantId(user.getTenantId());
		}else{
			return null;
		}
		//多部门支持in查询
		List<SysDepart> list = departMapper.queryUserDeparts(user.getId());
		List<String> sysMultiOrgCode = new ArrayList<String>();
		if(list==null || list.size()==0) {
			//当前用户无部门
			//sysMultiOrgCode.add("0");
		}else if(list.size()==1) {
			sysMultiOrgCode.add(list.get(0).getOrgCode());
		}else {
			info.setOneDepart(false);
			for (SysDepart dpt : list) {
				sysMultiOrgCode.add(dpt.getOrgCode());
			}
		}
		info.setSysMultiOrgCode(sysMultiOrgCode);
		return info;
	}

	@Override
	public LoginUser getUserById(String id) {
		if(oConvertUtils.isEmpty(id)) {
			return null;
		}
		LoginUser loginUser = new LoginUser();
		SysUser sysUser = userMapper.selectById(id);
		if(sysUser==null) {
			return null;
		}
		BeanUtils.copyProperties(sysUser, loginUser);
		return loginUser;
	}
	/**
	 * 6.1根据用户id查询用户信息
	 * @param tenantId
	 * @param newloginUser
	 * @return
	 */
	@Override
	public LoginUser addUser(String tenantId,LoginUser newloginUser){
		SysUser sysUser = new SysUser();
//		BaseTransfer<SysUser.class,LoginUser.class> baseTransfer = new BaseTransfer<SysUser.class,LoginUser.class>();
//		sysUser = BaseTransfer.toEntity(newloginUser);

		sysUser = ConversiontUtil.sourceToTarget(newloginUser,SysUser.class);
		//加密密码
		String salt = oConvertUtils.randomGen(8);
		sysUser.setSalt(salt);
		String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), newloginUser.getPassword(), salt);
		sysUser.setPassword(passwordEncode);

		sysUser.setCreateTime(new Date());//设置创建时间
		sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
//		sysUser.setRelTenantIds(String.valueOf(tenantId));
		sysUser.setTenantId(String.valueOf(tenantId));
		sysUser.setRelTenantIds(tenantId);
		if (oConvertUtils.isEmpty(sysUser.getDepartIds())) { //设置部门id
			sysUser.setDepartIds( getDepartIdsByOrgCode(newloginUser.getOrgCode()));
		}
		//此处可以根据用户身份，设置用户默认的角色，即老师、学生、班级、家长对应的角色，自动赋值，避免手动授权

		sysUserService.save(sysUser);
		newloginUser.setId(sysUser.getId());
		newloginUser.setPassword(passwordEncode);
		return newloginUser;
	}

	@Override
	public List<String> getRolesByUsername(String username) {
		return sysUserRoleMapper.getRoleByUserName(username);
	}

	@Override
	public List<String> getDepartIdsByUsername(String username) {
		List<SysDepart> list = sysDepartService.queryDepartsByUsername(username);
		List<String> result = new ArrayList<>(list.size());
		for (SysDepart depart : list) {
			result.add(depart.getId());
		}
		return result;
	}
	@Override
	public List<String> getSubDepIdsByDepId(String departId) {
		List<String> list = sysDepartService.getSubDepIdsByDepId(departId);
		return list;
	}
	@Override
	public String getStrSubDepIdsByDepId(String departId) {
		List<String> subDepIdsList = sysDepartService.getSubDepIdsByDepId(departId);
		String subDepIdsStr = "";
		//		List<String> result = new ArrayList<>(list.size());
		for (String onedepartId : subDepIdsList) {
			subDepIdsStr += onedepartId +",";
		}
		return subDepIdsStr;
	}
	@Override
	public String getSubDepOrgCodesByDepId(String departId) {
		String subDepIdsStr = getStrSubDepIdsByDepId(departId);
		List<JSONObject> subDepartsList = queryDepartsByIds(subDepIdsStr);
		String subDepSysOrgCode = "";
		for (JSONObject onedepart : subDepartsList) {
			subDepSysOrgCode += onedepart.getString("orgCode") +",";
		}

		return subDepSysOrgCode;
	}

	@Override
	public List<String> getDepartNamesByUsername(String username) {
		List<SysDepart> list = sysDepartService.queryDepartsByUsername(username);
		List<String> result = new ArrayList<>(list.size());
		for (SysDepart depart : list) {
			result.add(depart.getDepartName());
		}
		return result;
	}

	@Override
	public DictModel getParentDepartId(String departId) {
		SysDepart depart = departMapper.getParentDepartId(departId);
		DictModel model = new DictModel(depart.getId(),depart.getParentId());
		return model;
	}

	@Override
	@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code", unless = "#result == null ")
	public List<DictModel> queryDictItemsByCode(String code) {
		return sysDictService.queryDictItemsByCode(code);
	}

	@Override
	@Cacheable(value = CacheConstant.SYS_ENABLE_DICT_CACHE,key = "#code", unless = "#result == null ")
	public List<DictModel> queryEnableDictItemsByCode(String code) {
		return sysDictService.queryEnableDictItemsByCode(code);
	}

	@Override
	public List<DictModel> queryTableDictItemsByCode(String table, String text, String code) {
		//update-begin-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑，想法不错 LOWCOD-799
		if(table.indexOf("#{")>=0){
			table = QueryGenerator.getSqlRuleValue(table);
		}
		//update-end-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑，想法不错 LOWCOD-799
		return sysDictService.queryTableDictItemsByCode(table, text, code);
	}

	@Override
	public List<DictModel> queryAllDepartBackDictModel() {
		return sysDictService.queryAllDepartBackDictModel();
	}

	@Override
	public void sendSysAnnouncement(MessageDTO message) {
		this.sendSysAnnouncement(message.getFromUser(),
				message.getToUser(),
				message.getTitle(),
				message.getContent(),
				message.getCategory());
		try {
			// 同步发送第三方APP消息
			wechatEnterpriseService.sendMessage(message, true);
			dingtalkService.sendMessage(message, true);
		} catch (Exception e) {
			log.error("同步发送第三方APP消息失败！", e);
		}
	}

	@Override
	public void sendBusAnnouncement(BusMessageDTO message) {
		sendBusAnnouncement(message.getFromUser(),
				message.getToUser(),
				message.getTitle(),
				message.getContent(),
				message.getCategory(),
				message.getBusType(),
				message.getBusId());
		try {
			// 同步发送第三方APP消息
			wechatEnterpriseService.sendMessage(message, true);
			dingtalkService.sendMessage(message, true);
		} catch (Exception e) {
			log.error("同步发送第三方APP消息失败！", e);
		}
	}

	@Override
	public void sendTemplateAnnouncement(TemplateMessageDTO message) {
		String templateCode = message.getTemplateCode();
		String title = message.getTitle();
		Map<String,String> map = message.getTemplateParam();
		String fromUser = message.getFromUser();
		String toUser = message.getToUser();

		List<SysMessageTemplate> sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode);
		if(sysSmsTemplates==null||sysSmsTemplates.size()==0){
			throw new JeecgBootException("消息模板不存在，模板编码："+templateCode);
		}
		SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0);
		//模板标题
		title = title==null?sysSmsTemplate.getTemplateName():title;
		//模板内容
		String content = sysSmsTemplate.getTemplateContent();
		if(map!=null) {
			for (Map.Entry<String, String> entry : map.entrySet()) {
				String str = "${" + entry.getKey() + "}";
				if(oConvertUtils.isNotEmpty(title)){
					title = title.replace(str, entry.getValue());
				}
				content = content.replace(str, entry.getValue());
			}
		}

		SysAnnouncement announcement = new SysAnnouncement();
		announcement.setTitile(title);
		announcement.setMsgContent(content);
		announcement.setSender(fromUser);
		announcement.setPriority(CommonConstant.PRIORITY_M);
		announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
		announcement.setSendStatus(CommonConstant.HAS_SEND);
		announcement.setSendTime(new Date());
		announcement.setMsgCategory(CommonConstant.MSG_CATEGORY_2);
		announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
		sysAnnouncementMapper.insert(announcement);
		// 2.插入用户通告阅读标记表记录
		String userId = toUser;
		String[] userIds = userId.split(",");
		String anntId = announcement.getId();
		for(int i=0;i<userIds.length;i++) {
			if(oConvertUtils.isNotEmpty(userIds[i])) {
				SysUser sysUser = userMapper.getUserByName(userIds[i]);
				if(sysUser==null) {
					continue;
				}
				SysAnnouncementSend announcementSend = new SysAnnouncementSend();
				announcementSend.setAnntId(anntId);
				announcementSend.setUserId(sysUser.getId());
				announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
				sysAnnouncementSendMapper.insert(announcementSend);
				JSONObject obj = new JSONObject();
				obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
				obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
				obj.put(WebsocketConst.MSG_ID, announcement.getId());
				obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
				webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
			}
		}
		try {
			// 同步企业微信、钉钉的消息通知
			dingtalkService.sendActionCardMessage(announcement, true);
			wechatEnterpriseService.sendTextCardMessage(announcement, true);
		} catch (Exception e) {
			log.error("同步发送第三方APP消息失败！", e);
		}

	}

	@Override
	public void sendBusTemplateAnnouncement(BusTemplateMessageDTO message) {
		String templateCode = message.getTemplateCode();
		String title = message.getTitle();
		Map<String,String> map = message.getTemplateParam();
		String fromUser = message.getFromUser();
		String toUser = message.getToUser();
		String busId = message.getBusId();
		String busType = message.getBusType();

		List<SysMessageTemplate> sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode);
		if(sysSmsTemplates==null||sysSmsTemplates.size()==0){
			throw new JeecgBootException("消息模板不存在，模板编码："+templateCode);
		}
		SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0);
		//模板标题
		title = title==null?sysSmsTemplate.getTemplateName():title;
		//模板内容
		String content = sysSmsTemplate.getTemplateContent();
		if(map!=null) {
			for (Map.Entry<String, String> entry : map.entrySet()) {
				String str = "${" + entry.getKey() + "}";
				title = title.replace(str, entry.getValue());
				content = content.replace(str, entry.getValue());
			}
		}
		SysAnnouncement announcement = new SysAnnouncement();
		announcement.setTitile(title);
		announcement.setMsgContent(content);
		announcement.setSender(fromUser);
		announcement.setPriority(CommonConstant.PRIORITY_M);
		announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
		announcement.setSendStatus(CommonConstant.HAS_SEND);
		announcement.setSendTime(new Date());
		announcement.setMsgCategory(CommonConstant.MSG_CATEGORY_2);
		announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
		announcement.setBusId(busId);
		announcement.setBusType(busType);
		announcement.setOpenType(SysAnnmentTypeEnum.getByType(busType).getOpenType());
		announcement.setOpenPage(SysAnnmentTypeEnum.getByType(busType).getOpenPage());
		sysAnnouncementMapper.insert(announcement);
		// 2.插入用户通告阅读标记表记录
		String userId = toUser;
		String[] userIds = userId.split(",");
		String anntId = announcement.getId();
		for(int i=0;i<userIds.length;i++) {
			if(oConvertUtils.isNotEmpty(userIds[i])) {
				SysUser sysUser = userMapper.getUserByName(userIds[i]);
				if(sysUser==null) {
					continue;
				}
				SysAnnouncementSend announcementSend = new SysAnnouncementSend();
				announcementSend.setAnntId(anntId);
				announcementSend.setUserId(sysUser.getId());
				announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
				sysAnnouncementSendMapper.insert(announcementSend);
				JSONObject obj = new JSONObject();
				obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
				obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
				obj.put(WebsocketConst.MSG_ID, announcement.getId());
				obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
				webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
			}
		}
		try {
			// 同步企业微信、钉钉的消息通知
			dingtalkService.sendActionCardMessage(announcement, true);
			wechatEnterpriseService.sendTextCardMessage(announcement, true);
		} catch (Exception e) {
			log.error("同步发送第三方APP消息失败！", e);
		}

	}

	@Override
	public String parseTemplateByCode(TemplateDTO templateDTO) {
		String templateCode = templateDTO.getTemplateCode();
		Map<String, String> map = templateDTO.getTemplateParam();
		List<SysMessageTemplate> sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode);
		if(sysSmsTemplates==null||sysSmsTemplates.size()==0){
			throw new JeecgBootException("消息模板不存在，模板编码："+templateCode);
		}
		SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0);
		//模板内容
		String content = sysSmsTemplate.getTemplateContent();
		if(map!=null) {
			for (Map.Entry<String, String> entry : map.entrySet()) {
				String str = "${" + entry.getKey() + "}";
				content = content.replace(str, entry.getValue());
			}
		}
		return content;
	}

	@Override
	public void updateSysAnnounReadFlag(String busType, String busId) {
		SysAnnouncement announcement = sysAnnouncementMapper.selectOne(new QueryWrapper<SysAnnouncement>().eq("bus_type",busType).eq("bus_id",busId));
		if(announcement != null){
			LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
			String userId = sysUser.getId();
			LambdaUpdateWrapper<SysAnnouncementSend> updateWrapper = new UpdateWrapper().lambda();
			updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG);
			updateWrapper.set(SysAnnouncementSend::getReadTime, new Date());
			updateWrapper.last("where annt_id ='"+announcement.getId()+"' and user_id ='"+userId+"'");
			SysAnnouncementSend announcementSend = new SysAnnouncementSend();
			sysAnnouncementSendMapper.update(announcementSend, updateWrapper);
		}
	}

	/**
	 * 获取数据库类型
	 * @param dataSource
	 * @return
	 * @throws SQLException
	 */
	private String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException{
		if("".equals(DB_TYPE)) {
			Connection connection = dataSource.getConnection();
			try {
				DatabaseMetaData md = connection.getMetaData();
				String dbType = md.getDatabaseProductName().toLowerCase();
				if(dbType.indexOf("mysql")>=0) {
					DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL;
				}else if(dbType.indexOf("oracle")>=0) {
					DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE;
				}else if(dbType.indexOf("sqlserver")>=0||dbType.indexOf("sql server")>=0) {
					DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
				}else if(dbType.indexOf("postgresql")>=0) {
					DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
				}else if(dbType.indexOf("mariadb")>=0) {
					DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB;
				}else {
					log.error("数据库类型:[" + dbType + "]不识别!");
					//throw new JeecgBootException("数据库类型:["+dbType+"]不识别!");
				}
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}finally {
				connection.close();
			}
		}
		return DB_TYPE;

	}

	@Override
	public List<DictModel> queryAllDict() {
		// 查询并排序
		QueryWrapper<SysDict> queryWrapper = new QueryWrapper<SysDict>();
		queryWrapper.orderByAsc("create_time");
		List<SysDict> dicts = sysDictService.list(queryWrapper);
		// 封装成 model
		List<DictModel> list = new ArrayList<DictModel>();
		for (SysDict dict : dicts) {
			list.add(new DictModel(dict.getDictCode(), dict.getDictName()));
		}

		return list;
	}

	@Override
	public List<SysCategoryModel> queryAllSysCategory() {
		List<SysCategory> ls = categoryMapper.selectList(null);
		List<SysCategoryModel> res = oConvertUtils.entityListToModelList(ls,SysCategoryModel.class);
		return res;
	}

	@Override
	public List<DictModel> queryFilterTableDictInfo(String table, String text, String code, String filterSql) {
		return sysDictService.queryTableDictItemsByCodeAndFilter(table,text,code,filterSql);
	}

	@Override
	public List<String> queryTableDictByKeys(String table, String text, String code, String[] keyArray) {
		return sysDictService.queryTableDictByKeys(table,text,code,Joiner.on(",").join(keyArray));
	}

	@Override
	public List<ComboModel> queryAllUserBackCombo() {
		List<ComboModel> list = new ArrayList<ComboModel>();
		List<SysUser> userList = userMapper.selectList(new QueryWrapper<SysUser>().eq("status",1).eq("del_flag",0));
		for(SysUser user : userList){
			ComboModel model = new ComboModel();
			model.setTitle(user.getRealname());
			model.setId(user.getId());
			model.setUsername(user.getUsername());
			list.add(model);
		}
		return list;
	}

	@Override
	public JSONObject queryAllUser(String userIds, Integer pageNo, Integer pageSize) {
		JSONObject json = new JSONObject();
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().eq("status",1).eq("del_flag",0);
		List<ComboModel> list = new ArrayList<ComboModel>();
		Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
		IPage<SysUser> pageList = userMapper.selectPage(page, queryWrapper);
		for(SysUser user : pageList.getRecords()){
			ComboModel model = new ComboModel();
			model.setUsername(user.getUsername());
			model.setTitle(user.getRealname());
			model.setId(user.getId());
			model.setEmail(user.getEmail());
			if(oConvertUtils.isNotEmpty(userIds)){
				String[] temp = userIds.split(",");
				for(int i = 0; i<temp.length;i++){
					if(temp[i].equals(user.getId())){
						model.setChecked(true);
					}
				}
			}
			list.add(model);
		}
		json.put("list",list);
		json.put("total",pageList.getTotal());
		return json;
	}

	@Override
	public List<ComboModel> queryAllRole() {
		List<ComboModel> list = new ArrayList<ComboModel>();
		List<SysRole> roleList = roleMapper.selectList(new QueryWrapper<SysRole>());
		for(SysRole role : roleList){
			ComboModel model = new ComboModel();
			model.setTitle(role.getRoleName());
			model.setId(role.getId());
			list.add(model);
		}
		return list;
	}

    @Override
    public List<ComboModel> queryAllRole(String[] roleIds) {
        List<ComboModel> list = new ArrayList<ComboModel>();
        List<SysRole> roleList = roleMapper.selectList(new QueryWrapper<SysRole>());
        for(SysRole role : roleList){
            ComboModel model = new ComboModel();
            model.setTitle(role.getRoleName());
            model.setId(role.getId());
            model.setRoleCode(role.getRoleCode());
            if(oConvertUtils.isNotEmpty(roleIds)) {
                for (int i = 0; i < roleIds.length; i++) {
                    if (roleIds[i].equals(role.getId())) {
                        model.setChecked(true);
                    }
                }
            }
            list.add(model);
        }
        return list;
    }

	@Override
	public List<String> getRoleIdsByUsername(String username) {
		return sysUserRoleMapper.getRoleIdByUserName(username);
	}

	@Override
	public String getDepartIdsByOrgCode(String orgCode) {
		return departMapper.queryDepartIdByOrgCode(orgCode);
	}

	@Override
	public List<SysDepartModel> getAllSysDepart() {
		List<SysDepartModel> departModelList = new ArrayList<SysDepartModel>();
		List<SysDepart> departList = departMapper.selectList(new QueryWrapper<SysDepart>().eq("del_flag","0"));
		for(SysDepart depart : departList){
			SysDepartModel model = new SysDepartModel();
			BeanUtils.copyProperties(depart,model);
			departModelList.add(model);
		}
		return departModelList;
	}

	@Override
	public DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId) {
		SysDataSource dbSource = dataSourceService.getById(dbSourceId);
		if(dbSource!=null && StringUtils.isNotBlank(dbSource.getDbPassword())){
			String dbPassword = dbSource.getDbPassword();
			String decodedStr = SecurityUtil.jiemi(dbPassword);
			dbSource.setDbPassword(decodedStr);
		}
		return new DynamicDataSourceModel(dbSource);
	}

	@Override
	public DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode) {
		SysDataSource dbSource = dataSourceService.getOne(new LambdaQueryWrapper<SysDataSource>().eq(SysDataSource::getCode, dbSourceCode));
		if(dbSource!=null && StringUtils.isNotBlank(dbSource.getDbPassword())){
			String dbPassword = dbSource.getDbPassword();
			String decodedStr = SecurityUtil.jiemi(dbPassword);
			dbSource.setDbPassword(decodedStr);
		}
		return new DynamicDataSourceModel(dbSource);
	}

	@Override
	public List<String> getDeptHeadByDepId(String deptId) {
		List<SysUser> userList = userMapper.selectList(new QueryWrapper<SysUser>().like("depart_ids",deptId).eq("status",1).eq("del_flag",0));
		List<String> list = new ArrayList<>();
		for(SysUser user : userList){
			list.add(user.getUsername());
		}
		return list;
	}

	@Override
	public void sendWebSocketMsg(String[] userIds, String cmd) {
		JSONObject obj = new JSONObject();
		obj.put(WebsocketConst.MSG_CMD, cmd);
		webSocket.sendMessage(userIds, obj.toJSONString());
	}

	@Override
	public List<LoginUser> queryAllUserByIds(String[] userIds) {
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().eq("status",1).eq("del_flag",0);
		queryWrapper.in("id",userIds);
		List<LoginUser> loginUsers = new ArrayList<>();
		List<SysUser> sysUsers = userMapper.selectList(queryWrapper);
		for (SysUser user:sysUsers) {
			LoginUser loginUser=new LoginUser();
			BeanUtils.copyProperties(user, loginUser);
			loginUsers.add(loginUser);
		}
		return loginUsers;
	}

	/**
	 * 推送签到人员信息
	 * @param userId
	 */
	@Override
	public void meetingSignWebsocket(String userId) {
		JSONObject obj = new JSONObject();
		obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_SIGN);
		obj.put(WebsocketConst.MSG_USER_ID,userId);
		//TODO 目前全部推送，后面修改
		webSocket.sendMessage(obj.toJSONString());
	}

	@Override
	public List<LoginUser> queryUserByNames(String[] userNames) {
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().eq("status",1).eq("del_flag",0);
		queryWrapper.in("username",userNames);
		List<LoginUser> loginUsers = new ArrayList<>();
		List<SysUser> sysUsers = userMapper.selectList(queryWrapper);
		for (SysUser user:sysUsers) {
			LoginUser loginUser=new LoginUser();
			BeanUtils.copyProperties(user, loginUser);
			loginUsers.add(loginUser);
		}
		return loginUsers;
	}

	@Override
	public SysDepartModel selectAllById(String id) {
		SysDepart sysDepart = sysDepartService.getById(id);
		SysDepartModel sysDepartModel = new SysDepartModel();
		BeanUtils.copyProperties(sysDepart,sysDepartModel);
		return sysDepartModel;
	}

	@Override
	public List<String> queryDeptUsersByUserId(String userId) {
		List<String> userIds = new ArrayList<>();
		List<SysUserDepart> userDepartList = sysUserDepartService.list(new QueryWrapper<SysUserDepart>().eq("user_id",userId));
		if(userDepartList != null){
			//查找所属公司
			String orgCodes = "";
			for(SysUserDepart userDepart : userDepartList){
				//查询所属公司编码
				SysDepart depart = sysDepartService.getById(userDepart.getDepId());
				int length = YouBianCodeUtil.ZHANWEI_LENGTH;
				String compyOrgCode = "";
				if(depart != null && depart.getOrgCode() != null){
					compyOrgCode = depart.getOrgCode().substring(0,length);
					if(orgCodes.indexOf(compyOrgCode) == -1){
						orgCodes = orgCodes + "," + compyOrgCode;
					}
				}
			}
			if(oConvertUtils.isNotEmpty(orgCodes)){
				orgCodes = orgCodes.substring(1);
				List<String> listIds = departMapper.getSubDepIdsByOrgCodes(orgCodes.split(","));
				List<SysUserDepart> userList = sysUserDepartService.list(new QueryWrapper<SysUserDepart>().in("dep_id",listIds));
				for(SysUserDepart userDepart : userList){
					if(!userIds.contains(userDepart.getUserId())){
						userIds.add(userDepart.getUserId());
					}
				}
			}
		}
		return userIds;
	}

	/**
	 * 查询用户拥有的角色集合
	 * @param username
	 * @return
	 */
	@Override
	public Set<String> getUserRoleSet(String username) {
		// 查询用户拥有的角色集合
		List<String> roles = sysUserRoleMapper.getRoleByUserName(username);
		log.info("-------通过数据库读取用户拥有的角色Rules------username： " + username + ",Roles size: " + (roles == null ? 0 : roles.size()));
		return new HashSet<>(roles);
	}

	/**
	 * 查询用户拥有的权限集合
	 * @param username
	 * @return
	 */
	@Override
	public Set<String> getUserPermissionSet(String username) {
		Set<String> permissionSet = new HashSet<>();
		List<SysPermission> permissionList = sysPermissionMapper.queryByUser(username);
		for (SysPermission po : permissionList) {
//			// TODO URL规则有问题？
//			if (oConvertUtils.isNotEmpty(po.getUrl())) {
//				permissionSet.add(po.getUrl());
//			}
			if (oConvertUtils.isNotEmpty(po.getPerms())) {
				permissionSet.add(po.getPerms());
			}
		}
		log.info("-------通过数据库读取用户拥有的权限Perms------username： "+ username+",Perms size: "+ (permissionSet==null?0:permissionSet.size()) );
		return permissionSet;
	}

	/**
	 * 判断online菜单是否有权限
	 * @param onlineAuthDTO
	 * @return
	 */
	@Override
	public boolean hasOnlineAuth(OnlineAuthDTO onlineAuthDTO) {
		String username = onlineAuthDTO.getUsername();
		List<String> possibleUrl = onlineAuthDTO.getPossibleUrl();
		String onlineFormUrl = onlineAuthDTO.getOnlineFormUrl();
		//查询菜单
		LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
		query.eq(SysPermission::getDelFlag, 0);
		query.in(SysPermission::getUrl, possibleUrl);
		List<SysPermission> permissionList = sysPermissionMapper.selectList(query);
		if (permissionList == null || permissionList.size() == 0) {
			//没有配置菜单 找online表单菜单地址
			SysPermission sysPermission = new SysPermission();
			sysPermission.setUrl(onlineFormUrl);
			int count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
			if(count<=0){
				return false;
			}
		} else {
			//找到菜单了
			boolean has = false;
			for (SysPermission p : permissionList) {
				int count = sysPermissionMapper.queryCountByUsername(username, p);
				has = has || (count>0);
			}
			return has;
		}
		return true;
	}

	/**
	 * 查询用户拥有的角色集合 common api 里面的接口实现
	 * @param username
	 * @return
	 */
	@Override
	public Set<String> queryUserRoles(String username) {
		return getUserRoleSet(username);
	}

	/**
	 * 查询用户拥有的权限集合 common api 里面的接口实现
	 * @param username
	 * @return
	 */
	@Override
	public Set<String> queryUserAuths(String username) {
		return getUserPermissionSet(username);
	}

	/**
	 * 36根据多个用户账号(逗号分隔)，查询返回多个用户信息
	 * @param usernames
	 * @return
	 */
	@Override
	public List<JSONObject> queryUsersByUsernames(String usernames) {
		LambdaQueryWrapper<SysUser> queryWrapper =  new LambdaQueryWrapper<>();
		queryWrapper.in(SysUser::getUsername,usernames.split(","));
		return JSON.parseArray(JSON.toJSONString(userMapper.selectList(queryWrapper))).toJavaList(JSONObject.class);
	}

	@Override
	public List<JSONObject> queryUsersByIds(String ids) {
		LambdaQueryWrapper<SysUser> queryWrapper =  new LambdaQueryWrapper<>();
		queryWrapper.in(SysUser::getId,ids.split(","));
		return JSON.parseArray(JSON.toJSONString(userMapper.selectList(queryWrapper))).toJavaList(JSONObject.class);
	}

	/**
	 * 37根据多个部门编码(逗号分隔)，查询返回多个部门信息
	 * @param orgCodes
	 * @return
	 */
	@Override
	public List<JSONObject> queryDepartsByOrgcodes(String orgCodes) {
		LambdaQueryWrapper<SysDepart> queryWrapper =  new LambdaQueryWrapper<>();
		queryWrapper.in(SysDepart::getOrgCode,orgCodes.split(","));
		return JSON.parseArray(JSON.toJSONString(sysDepartService.list(queryWrapper))).toJavaList(JSONObject.class);
	}

	@Override
	public List<JSONObject> queryDepartsByIds(String ids) {
		LambdaQueryWrapper<SysDepart> queryWrapper =  new LambdaQueryWrapper<>();
		queryWrapper.in(SysDepart::getId,ids.split(","));
		return JSON.parseArray(JSON.toJSONString(sysDepartService.list(queryWrapper))).toJavaList(JSONObject.class);
	}

	/**
	 * 发消息
	 * @param fromUser
	 * @param toUser
	 * @param title
	 * @param msgContent
	 * @param setMsgCategory
	 */
	private void sendSysAnnouncement(String fromUser, String toUser, String title, String msgContent, String setMsgCategory) {
		SysAnnouncement announcement = new SysAnnouncement();
		announcement.setTitile(title);
		announcement.setMsgContent(msgContent);
		announcement.setSender(fromUser);
		announcement.setPriority(CommonConstant.PRIORITY_M);
		announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
		announcement.setSendStatus(CommonConstant.HAS_SEND);
		announcement.setSendTime(new Date());
		announcement.setMsgCategory(setMsgCategory);
		announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
		sysAnnouncementMapper.insert(announcement);
		// 2.插入用户通告阅读标记表记录
		String userId = toUser;
		String[] userIds = userId.split(",");
		String anntId = announcement.getId();
		for(int i=0;i<userIds.length;i++) {
			if(oConvertUtils.isNotEmpty(userIds[i])) {
				SysUser sysUser = userMapper.getUserByName(userIds[i]);
				if(sysUser==null) {
					continue;
				}
				SysAnnouncementSend announcementSend = new SysAnnouncementSend();
				announcementSend.setAnntId(anntId);
				announcementSend.setUserId(sysUser.getId());
				announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
				sysAnnouncementSendMapper.insert(announcementSend);
				JSONObject obj = new JSONObject();
				obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
				obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
				obj.put(WebsocketConst.MSG_ID, announcement.getId());
				obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
				webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
			}
		}

	}

	/**
	 * 发消息 带业务参数
	 * @param fromUser
	 * @param toUser
	 * @param title
	 * @param msgContent
	 * @param setMsgCategory
	 * @param busType
	 * @param busId
	 */
	private void sendBusAnnouncement(String fromUser, String toUser, String title, String msgContent, String setMsgCategory, String busType, String busId) {
		SysAnnouncement announcement = new SysAnnouncement();
		announcement.setTitile(title);
		announcement.setMsgContent(msgContent);
		announcement.setSender(fromUser);
		announcement.setPriority(CommonConstant.PRIORITY_M);
		announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
		announcement.setSendStatus(CommonConstant.HAS_SEND);
		announcement.setSendTime(new Date());
		announcement.setMsgCategory(setMsgCategory);
		announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
		announcement.setBusId(busId);
		announcement.setBusType(busType);
		announcement.setOpenType(SysAnnmentTypeEnum.getByType(busType).getOpenType());
		announcement.setOpenPage(SysAnnmentTypeEnum.getByType(busType).getOpenPage());
		sysAnnouncementMapper.insert(announcement);
		// 2.插入用户通告阅读标记表记录
		String userId = toUser;
		String[] userIds = userId.split(",");
		String anntId = announcement.getId();
		for(int i=0;i<userIds.length;i++) {
			if(oConvertUtils.isNotEmpty(userIds[i])) {
				SysUser sysUser = userMapper.getUserByName(userIds[i]);
				if(sysUser==null) {
					continue;
				}
				SysAnnouncementSend announcementSend = new SysAnnouncementSend();
				announcementSend.setAnntId(anntId);
				announcementSend.setUserId(sysUser.getId());
				announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
				sysAnnouncementSendMapper.insert(announcementSend);
				JSONObject obj = new JSONObject();
				obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
				obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
				obj.put(WebsocketConst.MSG_ID, announcement.getId());
				obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
				webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
			}
		}
	}

	/**
	 * 发送邮件消息
	 * @param email
	 * @param title
	 * @param content
	 */
	@Override
	public void sendEmailMsg(String email, String title, String content) {
			EmailSendMsgHandle emailHandle=new EmailSendMsgHandle();
			emailHandle.SendMsg(email, title, content);
	}

	/**
	 * 获取公司下级部门和所有用户id信息
	 * @param orgCode
	 * @return
	 */
	@Override
	public List<Map> getDeptUserByOrgCode(String orgCode) {
		//1.获取公司信息
		SysDepart comp=sysDepartService.queryCompByOrgCode(orgCode);
		if(comp!=null){
			//2.获取公司下级部门
			List<SysDepart> departs=sysDepartService.queryDeptByPid(comp.getId());
			//3.获取部门下的人员信息
			 List<Map> list=new ArrayList();
			 //4.处理部门和下级用户数据
			for (SysDepart dept:departs) {
				Map map=new HashMap(5);
				//部门名称
				String departName = dept.getDepartName();
				//根据部门编码获取下级部门id
				List<String> listIds = departMapper.getSubDepIdsByDepId(dept.getId());
				//根据下级部门ids获取下级部门的所有用户
				List<SysUserDepart> userList = sysUserDepartService.list(new QueryWrapper<SysUserDepart>().in("dep_id",listIds));
				List<String> userIds = new ArrayList<>();
				for(SysUserDepart userDepart : userList){
					if(!userIds.contains(userDepart.getUserId())){
						userIds.add(userDepart.getUserId());
					}
				}
				map.put("name",departName);
				map.put("ids",userIds);
				list.add(map);
			}
			return list;
		}
		return null;
	}

	/**
	 * 查询分类字典翻译
	 *
	 * @param ids 分类字典表id
	 * @return
	 */
	@Override
	public List<String> loadCategoryDictItem(String ids) {
		return sysCategoryService.loadDictItem(ids, false);
	}

	/**
	 * 根据字典code加载字典text
	 *
	 * @param dictCode 顺序：tableName,text,code
	 * @param keys     要查询的key
	 * @return
	 */
	@Override
	public List<String> loadDictItem(String dictCode, String keys) {
		String[] params = dictCode.split(",");
		return sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys, false);
	}

	/**
	 * 根据字典code查询字典项
	 *
	 * @param dictCode 顺序：tableName,text,code
	 * @param dictCode 要查询的key
	 * @return
	 */
	@Override
	public List<DictModel> getDictItems(String dictCode) {
		List<DictModel> ls = sysDictService.getDictItems(dictCode);
		if (ls == null) {
			ls = new ArrayList<>();
		}
		return ls;
	}

	/**
	 * 根据多个字典code查询多个字典项
	 *
	 * @param dictCodeList
	 * @return key = dictCode ； value=对应的字典项
	 */
	@Override
	public Map<String, List<DictModel>> getManyDictItems(List<String> dictCodeList) {
		return sysDictService.queryDictItemsByCodeList(dictCodeList);
	}

	/**
	 * 【下拉搜索】
	 * 大数据量的字典表 走异步加载，即前端输入内容过滤数据
	 *
	 * @param dictCode 字典code格式：table,text,code
	 * @param keyword  过滤关键字
	 * @return
	 */
	@Override
	public List<DictModel> loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize) {
		return sysDictService.loadDict(dictCode, keyword, pageSize);
	}

	@Override
	public Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys) {
		List<String> dictCodeList = Arrays.asList(dictCodes.split(","));
		List<String> values = Arrays.asList(keys.split(","));
		return sysDictService.queryManyDictByKeys(dictCodeList, values);
	}

	@Override
	public List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys) {
		return sysDictService.queryTableDictTextByKeys(table, text, code, Arrays.asList(keys.split(",")));
	}

	@Override
	public LoginUser getOneUser(String username) {
		SysUser user = userMapper.getOneUser(username);

		LoginUser loginUser = new LoginUser();
		BeanUtil.copyProperties(user,loginUser);
		return loginUser;
	}
	@Override
	public SysTenantVo  getSysTenant(String tenantId) {
		SysTenant sysTenant = sysTenantService.getById(tenantId);
		SysTenantVo sysTenantVo = ConversiontUtil.sourceToTarget(sysTenant,SysTenantVo.class);
		return sysTenantVo;

	}
	@Override
	public String createTenantAdminRoleUser(int tenantId){
		SysTenant sysTenant = sysTenantService.getById(tenantId);
//		//没有角色则创建，有角色则跳过:都在复制中解决
//		String roleCode = sysTenant.getPreCode()+"_admin";
//		Map<String,Object> sysRoleSeelctMap = new HashMap<String,Object>();
//		sysRoleSeelctMap.put("tenant_id",String.valueOf(tenantId));
//		sysRoleSeelctMap.put("role_code",roleCode);
//		List<SysRole> sysRoleList = sysRoleService.listByMap(sysRoleSeelctMap);
//		// 添加admin角色:目标不存在则添加，存在则忽略
//		SysRole role = new SysRole();
//		if(oConvertUtils.listIsEmpty(sysRoleList)) {
//			role.setRoleCode(roleCode);
//			role.setRoleName(sysTenant.getName() + "管理员角色");
//			role.setTenantId(tenantId);
//			sysRoleService.save(role);
//		}
//		else{
//			role = sysRoleList.get(0);
//		}
//
//
//
//
//
//		// 添加顶层部门:目标不存在则添加，存在则忽略:都在复制中解决
//		SysDepart sysdepart = new SysDepart();
//		sysdepart.setDepartName(sysTenant.getName());
//		sysdepart.setOrgCategory(String.valueOf(1)); //公司
//		sysdepart.setOrgType(String.valueOf(1)); //一级部门
//		sysdepart.setOrgCode(String.valueOf(tenantId)); //部门编码
//		sysdepart.setDelFlag(String.valueOf(0));
//		sysdepart.setTenantId(tenantId); //租户id
//		Map<String,Object>  queryMap = MapBeanUtils.bean2Map(sysdepart);
////		QueryWrapper<SysDepart> queryWrapper = QueryGenerator.initQueryWrapper(sysdepart,queryMap);
////		List<SysDepart> sysdepartList = sysDepartService.listObjs(queryWrapper);
//		queryMap.put("tenant_id",String.valueOf(tenantId));
//		queryMap.put("org_code",String.valueOf(tenantId));
//		List<SysDepart> sysdepartList = sysDepartService.listByMap(queryMap);
//
//		if(oConvertUtils.listIsEmpty(sysdepartList)){
//			sysDepartService.save(sysdepart);
//		}
//		else{
//			sysdepart = sysdepartList.get(0);
//		}

		//添加默认登录用户：租户超级管理员
		SysUser tenantAdminuser = new SysUser();
		String adminUsername = sysTenant.getPreCode()+"_admin";
		String adminPwd = adminUsername; //默认用户名密码一致
		tenantAdminuser.setUsername(adminUsername);
		String salt = oConvertUtils.randomGen(8);
		tenantAdminuser.setSalt(salt);
		String passwordEncode = PasswordUtil.encrypt(adminUsername, adminPwd, salt);
		tenantAdminuser.setPassword(passwordEncode);
		tenantAdminuser.setRealname(sysTenant.getName()+"管理员admin");
		tenantAdminuser.setDelFlag(CommonConstant.DEL_FLAG_0);
		tenantAdminuser.setTenantId(String.valueOf(tenantId));

		Map<String,Object>  adminUserQueryMap = new HashMap<String,Object>() ;// MapBeanUtils.bean2Map(tenantAdminuser);
		adminUserQueryMap.put("tenant_id",String.valueOf(tenantId));
		adminUserQueryMap.put("username",adminUsername);
		List<SysUser> sysUserList = sysUserService.listByMap(adminUserQueryMap);


		if(oConvertUtils.listIsEmpty(sysUserList)){

			QueryWrapper<SysDepart> sysDepartQueryWrapper = new QueryWrapper<>();
			sysDepartQueryWrapper.eq("tenant_id",tenantId);
			sysDepartQueryWrapper.eq("org_code",String.valueOf(tenantId));
			sysDepartQueryWrapper.isNull("parent_id");
			SysDepart sysDepart = sysDepartService.getOne(sysDepartQueryWrapper);

			tenantAdminuser.setDepartIds(sysDepart.getId());
			tenantAdminuser.setUserIdentity(2);
			tenantAdminuser.setStatus(1);
			tenantAdminuser.setRelTenantIds(String.valueOf(tenantId));
//			tenantAdminuser.setCreateTime(new Date());//设置创建时间
			tenantAdminuser.setUpdateBy("admin(sys)");
			tenantAdminuser.setCreateTime(DateUtil.getCurrentDate());
			tenantAdminuser.setUpdateBy(null);
			tenantAdminuser.setUpdateTime(null);
			sysUserService.save(tenantAdminuser);
		}
		else{
			tenantAdminuser = sysUserList.get(0);
		}


		//人员所属部门关系(新增人员时分配）
		//查找管理员角色
		QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
		sysRoleQueryWrapper.eq("tenant_id",tenantId);
		sysRoleQueryWrapper.eq("role_code",sysTenant.getPreCode()+"_admin");
//		sysRoleQueryWrapper.like("role_code","_admin");
		SysRole sysRole = sysRoleService.getOne(sysRoleQueryWrapper);
		// 添加角色 用户关系(授权）
		SysUserRole sysUserRole2 = new SysUserRole();
		// TODO is ok？
		sysUserRole2.setRoleId(sysRole.getId());
		sysUserRole2.setUserId(tenantAdminuser.getId());
		Map<String,Object>  sysUserRoleQueryMap = new HashMap<String,Object>();//MapBeanUtils.bean2Map(sysUserRole2);
		sysUserRoleQueryMap.put("role_id",sysRole.getId());
		sysUserRoleQueryMap.put("user_id",tenantAdminuser.getId());
		List<SysUserRole> sysUserRoleList = sysUserRoleService.listByMap(sysUserRoleQueryMap);

//		QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
//		sysUserRoleQueryWrapper.eq("tenant_id",tenantId);
//		sysUserRoleQueryWrapper.like("role_code","_admin");
//		SysUserRole sysUserRole = sysUserRoleService.getOne(sysUserRoleQueryWrapper);

		if(oConvertUtils.listIsEmpty(sysUserRoleList)){
			sysUserRoleService.save(sysUserRole2);
		}
		else{
			sysUserRole2 = sysUserRoleList.get(0);
		}


		return tenantAdminuser.getId();
	}
	@Override
	public boolean copyCloneTenantMenuRoleDepart(String sourceTenantId,String targetTenantId,String copyCloneObjTypes){

		SysTenant sourceSysTenant = sysTenantService.getById(Integer.valueOf(sourceTenantId));
		SysTenant targetSysTenant = sysTenantService.getById(Integer.valueOf(targetTenantId));
		Map<String, Object> queryMap = new HashMap<String, Object>();
		//复制菜单:目标不存在则复制，存在则忽略
		if(copyCloneObjTypes.indexOf("SysPermission") != -1) {
			queryMap.put("tenant_id", sourceTenantId);
			List<SysPermission> sourceSysPermissionList = sysPermissionService.listByMap(queryMap);
			queryMap.put("tenant_id", targetTenantId);
			List<SysPermission> targetSysPermissionList = sysPermissionService.listByMap(queryMap);
			if (oConvertUtils.listIsNotEmpty(sourceSysPermissionList) && oConvertUtils.listIsEmpty(targetSysPermissionList)) {
				for (SysPermission p : sourceSysPermissionList) {
					p.setId(null);
					p.setTenantId(Integer.valueOf(targetTenantId));
					p.setUpdateBy("admin(sys)");
					p.setCreateTime(DateUtil.getCurrentDate());
					p.setUpdateBy(null);
					p.setUpdateTime(null);
				}
				sysPermissionService.saveBatch(sourceSysPermissionList);
				//设置菜单的上下级关系
				//更新上下级关系
				queryMap.put("tenant_id", targetTenantId);
				targetSysPermissionList = sysPermissionService.listByMap(queryMap);
//				for(SysPermission p2:targetSysPermissionList){//for循环遇到remove报错
				Iterator it = targetSysPermissionList.iterator();
				while(it.hasNext()){
					SysPermission p2 = (SysPermission)it.next();
					String oldParentId = p2.getParentId();
					if(oConvertUtils.isNotEmpty(oldParentId)) {
						SysPermission oldSysPermissionByParentId = sysPermissionService.getById(oldParentId);
						if(oConvertUtils.isEmpty(oldSysPermissionByParentId)){
							//如果原上级父菜单不存在，则该菜单无效
//							targetSysPermissionList.remove(p2);//,remove会导致循环报错
							continue;
						}
						QueryWrapper<SysPermission> sysPermissionQueryWrapper = new QueryWrapper<SysPermission>();
						sysPermissionQueryWrapper.eq("name",oldSysPermissionByParentId.getName());
						sysPermissionQueryWrapper.eq("url",oldSysPermissionByParentId.getUrl());
						sysPermissionQueryWrapper.eq("component",oldSysPermissionByParentId.getComponent());
						sysPermissionQueryWrapper.eq("tenant_id",targetSysTenant.getId());

						List<SysPermission> newSysPermissionByParentIdList = sysPermissionService.list(sysPermissionQueryWrapper);

						if(oConvertUtils.listIsNotEmpty(newSysPermissionByParentIdList)){
							SysPermission newSysPermissionByParentId = newSysPermissionByParentIdList.get(0);
							p2.setParentId(newSysPermissionByParentId.getId());
						}
						else{
							p2.setParentId(null);
							p2.setMenuType(1);//一级菜单
						}
					}
					else{
						p2.setParentId(null);
						p2.setMenuType(1);//一级菜单
					}

				}
				//
				sysPermissionService.updateBatchById(targetSysPermissionList);

			}
		}

		//复制角色:目标不存在则复制，存在则忽略(初始化时候会初始化1个超级管理员角色不算）
		if(copyCloneObjTypes.indexOf("SysRole") != -1) {
			queryMap.put("tenant_id", sourceTenantId);
			List<SysRole> sourceSysRoleList = sysRoleService.listByMap(queryMap);
			queryMap.put("tenant_id", targetTenantId);
			List<SysRole> targetSysRoleList = sysRoleService.listByMap(queryMap);
			if (oConvertUtils.listIsNotEmpty(sourceSysRoleList) && (oConvertUtils.listIsEmpty(targetSysRoleList) || targetSysRoleList.size() <= 1)) {
				for (SysRole p : sourceSysRoleList) {
					p.setId(null);
					p.setTenantId(Integer.valueOf(targetTenantId));
					String newRoleCode = p.getRoleCode().replace(sourceSysTenant.getPreCode(),targetSysTenant.getPreCode());
					p.setRoleCode(newRoleCode);//替换租户角色前缀
					String newRoleName = p.getRoleName().replace(sourceSysTenant.getName(),targetSysTenant.getName());
					p.setRoleName(newRoleName);
					p.setUpdateBy("admin(sys)");
					p.setCreateTime(DateUtil.getCurrentDate());
					p.setUpdateBy(null);
					p.setUpdateTime(null);
				}
				//循环移除无效数据（id存在的数据是无效的,倒序循环移除无效数据）
//				for(int i=sourceSysRoleList.size();i>=0;i++){
//					if(oConvertUtils.isNotEmpty(sourceSysRoleList.get(i).getId()){
//				sysRoleService.removeById(sourceSysRoleList.get(i).getId());
//						sourceSysRoleList.remove(i);
//					}
//				}
				sysRoleService.saveBatch(sourceSysRoleList);
			}
		}
		//权限：角色和菜单关系（权限）
		if(copyCloneObjTypes.indexOf("SysRolePermission") != -1 ){
			queryMap.put("tenant_id", targetTenantId);
			List<SysRolePermission> targertSysRolePermissionList = sysRolePermissionService.listByMap(queryMap);
			queryMap.put("tenant_id", sourceTenantId);
			List<SysRolePermission> sourceSysRolePermissionList = sysRolePermissionService.listByMap(queryMap);
			if((oConvertUtils.listIsEmpty(targertSysRolePermissionList) ||targertSysRolePermissionList.size() <=1 ) && oConvertUtils.listIsNotEmpty(sourceSysRolePermissionList)) {

//				for (SysRolePermission p : sourceSysRolePermissionList) {//for循环遇到remove报错
				Iterator it = sourceSysRolePermissionList.iterator();
				while(it.hasNext()){
					SysRolePermission p = (SysRolePermission)it.next();
					if (oConvertUtils.isEmpty(p.getRoleId())) {
//						sourceSysRolePermissionList.remove(p);//无效的id，可以忽略,remove会导致循环报错
						continue;
					}
					SysRole oldSysRole = sysRoleService.getById(p.getRoleId());
					if (oConvertUtils.isEmpty(oldSysRole)) {
//						sourceSysRolePermissionList.remove(p);//无效的id，可以忽略,remove会导致循环报错
						continue;
					}
					QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<SysRole>();
					String newRoleCode = oldSysRole.getRoleCode().replace(sourceSysTenant.getPreCode(), targetSysTenant.getPreCode());
					sysRoleQueryWrapper.eq("role_code", newRoleCode);
					String newRoleName = oldSysRole.getRoleName().replace(sourceSysTenant.getName(), targetSysTenant.getName());
//				sysRoleQueryWrapper.eq("role_Name",newRoleName);
					sysRoleQueryWrapper.eq("tenant_id", targetSysTenant.getId());

					List<SysRole> newSysRoleList = sysRoleService.list(sysRoleQueryWrapper);
					SysRole newSysRole = newSysRoleList.get(0);

					SysPermission oldSysPermission = sysPermissionService.getById(p.getPermissionId());
					if (oConvertUtils.isEmpty(oldSysPermission)) {
						//如果原关联权限的菜单不存在，则该菜单无效或无权限
//						sourceSysRolePermissionList.remove(p);////无效的id，可以忽略,remove会导致循环报错
						continue;
					}
					QueryWrapper<SysPermission> sysPermissionWrapper = new QueryWrapper<SysPermission>();
					sysPermissionWrapper.eq("name", oldSysPermission.getName());
					sysPermissionWrapper.eq("url", oldSysPermission.getUrl());
					sysPermissionWrapper.eq("component", oldSysPermission.getComponent());
					sysPermissionWrapper.eq("tenant_id", targetSysTenant.getId());
					List<SysPermission> newSysPermissionList = sysPermissionService.list(sysPermissionWrapper);
					SysPermission newSysPermission = newSysPermissionList.get(0);
					if (oConvertUtils.isNotEmpty(newSysRole) && oConvertUtils.isNotEmpty(newSysPermission)) {
						p.setId(null);
						p.setRoleId(newSysRole.getId());
						p.setPermissionId(newSysPermission.getId());
						p.setOperateDate(DateUtil.getCurrentDate());
						p.setOperateIp(null);
						p.setTenantId(targetSysTenant.getId());
					} else {
						sourceSysRolePermissionList.remove(p);
					}
				}
				if (oConvertUtils.listIsNotEmpty(sourceSysRolePermissionList)) {
					//循环移除无效数据（id存在的数据是无效的,倒序循环移除无效数据）
					for(int i=sourceSysRolePermissionList.size()-1;i>=0;i--){
						if(oConvertUtils.isNotEmpty(sourceSysRolePermissionList.get(i).getId())){
							sysRolePermissionService.removeById(sourceSysRolePermissionList.get(i).getId());
							sourceSysRolePermissionList.remove(i);
						}
					}
					sysRolePermissionService.saveBatch(sourceSysRolePermissionList);
				}
			}
		}

		//复制部门:目标不存在则复制，存在则忽略
		if(copyCloneObjTypes.indexOf("SysDepart") != -1) {
			queryMap.put("tenant_id", sourceTenantId);
			List<SysDepart> sourceSysDepartList = sysDepartService.listByMap(queryMap);
			queryMap.put("tenant_id", targetTenantId);
			List<SysDepart> targetSysDepartList = sysDepartService.listByMap(queryMap);
			if (oConvertUtils.listIsNotEmpty(sourceSysDepartList) && oConvertUtils.listIsEmpty(targetSysDepartList)) {
				for (SysDepart p : sourceSysDepartList) {
					p.setId(null);
					p.setTenantId(Integer.valueOf(targetTenantId));
					// 1公司 1一级部门
 					if(sourceTenantId.equals(p.getOrgCode()) ) {//"1".equals(p.getOrgCategory()) && "1".equals(p.getOrgType())
						p.setDepartName(targetSysTenant.getName());
					}
 					String newOrgCode = p.getOrgCode().replace(sourceSysTenant.getPreCode(),targetSysTenant.getPreCode()).replace(sourceSysTenant.getId().toString(),targetSysTenant.getId().toString());
 					p.setOrgCode(newOrgCode);

					p.setUpdateBy("admin(sys)");
					p.setCreateTime(DateUtil.getCurrentDate());
					p.setUpdateBy(null);
					p.setUpdateTime(null);
				}
				sysDepartService.saveBatch(sourceSysDepartList);
				//更新上下级关系
				queryMap.put("tenant_id", targetTenantId);
				targetSysDepartList = sysDepartService.listByMap(queryMap);
//				for(SysDepart p2:targetSysDepartList){//for循环遇到remove报错
				Iterator it = targetSysDepartList.iterator();
				while(it.hasNext()){
					SysDepart p2 = (SysDepart)it.next();
					String oldParentId = p2.getParentId();
					if(oConvertUtils.isNotEmpty(oldParentId)) {
						SysDepart oldSysDepartByParentId = sysDepartService.getById(oldParentId);
						if(oConvertUtils.isEmpty(oldSysDepartByParentId)){
							p2.setParentId(null);
//							targetSysDepartList.remove(p2);//上级部门不存在，属于无效部门，可忽略
							continue;
						}
						queryMap.put("tenant_id", targetTenantId);
//					queryMap.put("depart_name",oldSysDepartByParentId.getDepartName());
						String newOrgCode = oldSysDepartByParentId.getOrgCode().replace(sourceSysTenant.getPreCode(), targetSysTenant.getPreCode()).replace(sourceSysTenant.getId().toString(), targetSysTenant.getId().toString());
						queryMap.put("org_code", newOrgCode);

						List<SysDepart> newSysDepartByParentIdList = sysDepartService.listByMap(queryMap);
						if(oConvertUtils.listIsNotEmpty(newSysDepartByParentIdList)){
							SysDepart newSysDepartByParentId = newSysDepartByParentIdList.get(0);
							p2.setParentId(newSysDepartByParentId.getId());
						}
						else{
							p2.setParentId(null);
//							targetSysDepartList.remove(p2);//,remove会导致循环报错
							continue;
						}
					}
					else{
						p2.setParentId(null);
					}

					if(oConvertUtils.isEmpty(p2.getParentId()) ){
						QueryWrapper<SysDepart> sysDepartQueryWrapper = new QueryWrapper<SysDepart>();
						sysDepartQueryWrapper.eq("tenant_id", targetTenantId);
						sysDepartQueryWrapper.isNull("parent_id");
						sysDepartQueryWrapper.eq("org_code",targetTenantId);
						SysDepart newSysDepart = sysDepartService.getOne(sysDepartQueryWrapper);
						p2.setParentId(newSysDepart.getId());
						if(p2.getParentId().equals(newSysDepart.getId())){
							p2.setParentId(null);
						}

					}
				}
				sysDepartService.updateBatchById(targetSysDepartList);

			}
		}
		//创建管理员用户
		if(copyCloneObjTypes.indexOf("createAdminUser") != -1) {
			createTenantAdminRoleUser(Integer.valueOf(targetTenantId));
		}
		return true;
	}

}